	//
	//  GaoMenuView.m
	//  JsoMediaCaptureViewController
	//
	//  Created by Gikki Ares on 2020/9/25.
	//

#import "JsMenuView.h"
#import "JsMenuItemView.h"
#import "JsMenuItemVm.h"
#import "JsMenuDefaultItemView.h"
#import "JsMenuCollectionView.h"

@interface Prefix(MenuView)()<
UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout
>
{
	UICollectionView *mcv;
	NSArray <JsMenuItemVm *> * marr;
	
	Prefix(MenuViewStyle) * mgaoMenuViewStyle;
	
		//显示当前选择项目的MaskView;
	UIView * mv_mask;
	
		//显示当前选择项目的Indicator;
	BOOL mb_isIndicatorEnable;
	
	UIView * mv_indicator;
	
	NSIndexPath * mnsIndexPath_selected;
	
	BOOL mb_willReload;
}

@end

@implementation Prefix(MenuView)
#pragma mark 1 SystemCycle
- (instancetype)initWithFrame:(CGRect)frame {
	if(self = [super initWithFrame:frame]) {
//		[self commonInit];
	}
	return self;
}


	//xib加载,会调用此方法初始化,但是子视图是在awakeFromNib中加载出来的.
	//跟视图init的时候,自view没有加载出来,应该放到awakFromNib...
- (instancetype)initWithCoder:(NSCoder *)coder {
	if(self = [super initWithCoder:coder]) {
	}
	return self;
}


- (void)awakeFromNib {
	[super awakeFromNib];
//	[self commonInit];
}
	//什么情况?这里死循环了??
- (void)layoutSubviews {
	[super layoutSubviews];
	mcv.frame = self.bounds;
		//FIXME: 为什么颜色设置为白色,进入后台后,再返回前台会掩盖cell的颜色?
		//	mcv.backgroundColor = [UIColor whiteColor];
	
}

- (UICollectionView *)collectionView {
	return self->mcv;
}

#define CellReuseIdentifier @"cell"
- (void)commonInitWithScrollDirection:(UICollectionViewScrollDirection)scrollDirection {
		//owner的作用,就是将nib中的元素,绑定到self的属性.
	self.autoresizingMask = UIViewAutoresizingNone;
	UICollectionViewFlowLayout * layout =  [UICollectionViewFlowLayout new];
	layout.scrollDirection = scrollDirection;
	mcv = [[JsMenuCollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
	mcv.delegate = self;
	mcv.dataSource = self;
	mcv.backgroundColor = [UIColor clearColor];
	mcv.bounces = NO;
	
	//如果实现了代理方法,则调用代理方法注册自定义的cell,否则,注册默认的cell.注册cell
	JsMenuItemView * cell = nil;
	UINib * nib = nil;
	if([self.delegate respondsToSelector:@selector(_jsMenuViewGetRegisterCellClass:)]) {
		cell = [self.delegate _jsMenuViewGetRegisterCellClass:self];
	}
	
	if(cell) {
		[mcv registerClass:[cell class] forCellWithReuseIdentifier:CellReuseIdentifier];
	}
	else {
		if([self.delegate respondsToSelector:@selector(_jsMenuViewGetRegisterCellNib:)]) {
			nib = [self.delegate _jsMenuViewGetRegisterCellNib:self];
		}
		if(nib) {
			[mcv registerNib:nib forCellWithReuseIdentifier:CellReuseIdentifier];
		}
		else {
			[mcv registerClass:[JsMenuDefaultItemView class] forCellWithReuseIdentifier:CellReuseIdentifier];
		}
	}
	
	if (@available(iOS 11.0, *)) {
		mcv.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
	} else {
			// Fallback on earlier versions
	}
//	if (@available(iOS 13.0, *)) {
//		mcv.automaticallyAdjustsScrollIndicatorInsets = NO;
//	} else {
//			// Fallback on earlier versions
//	}
	[self addSubview:mcv];
	
}

- (void)setupByDelegate {
	//得到style,直接调用getStyle就好了
	if(_delegate && [_delegate respondsToSelector:@selector(jsMenuViewSetStyle:)]){
		mgaoMenuViewStyle = [_delegate jsMenuViewSetStyle:self];
	}
	if(!mgaoMenuViewStyle) {
		mgaoMenuViewStyle = [Prefix(MenuViewStyle) defaultStyle];
	}
		//确定滑动方向后,才能开始初始化UICollectionView
	[self commonInitWithScrollDirection:mgaoMenuViewStyle.scrollDirection];
	[self reload];
}
- (void)setDelegate:(id<Prefix(MenuViewDelegate)>)delegate {
	_delegate = delegate;
	
		//这里加dispatch,是因为设置代理的runloop中,可能还需要设置其他的项目;
		//如果这些属性在设置代理之后,就不起作用了.
	dispatch_async(dispatch_get_main_queue(), ^{
		[self setupByDelegate];
	});
	
}



#pragma mark 2 Interface
- (void)setMgaoMenuViewStyle:(Prefix(MenuViewStyle) *)mgaoMenuViewStyle {
		//设置背景色
	mcv.backgroundColor = mgaoMenuViewStyle.collectionViewBackgroundColor;
		//设置初始选择的项目,选中不选中,一定要改变model中的值,然后reload此cell的方式.
	
	if(mgaoMenuViewStyle.isShowChooseMaskView) {
		mv_mask = [[UIView alloc]init];
			//关闭遮罩的响应,这样才能多次点击同一个按钮.否则遮罩挡住了,点不到.
		mv_mask.userInteractionEnabled = NO;
		mv_mask.hidden = YES;
		mv_mask.backgroundColor = mgaoMenuViewStyle.maskViewColor;
		[self addSubview:mv_mask];
		mv_mask.frame = CGRectZero;
	}
	
		//为什么这里调用会导致死循环?
	if(mgaoMenuViewStyle.mb_isShowIndicator) {
		self->mv_indicator = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 1, 1)];
		self->mv_indicator.hidden = YES;
		self->mv_indicator.backgroundColor = mgaoMenuViewStyle.chooseIndicatorColor;
			//TODO: 这里如果加在self上,会导致self,viewDidLayoutSubviews死循环.
		[self addSubview:self->mv_indicator];
	}
}

- (void)setModelArray:(NSArray <JsMenuItemVm *>*)arr {
	self->marr = arr;
	[self->mcv reloadData];
}


//MenuView取消选择,不选择任意item.
- (void)unselect {
	if(mnsIndexPath_selected) {
		int i_index_selected = (int)mnsIndexPath_selected.item;
		NSIndexPath * nsIndexPath = [NSIndexPath indexPathForItem:i_index_selected inSection:0];
		if(nsIndexPath) {
			JsMenuItemView * cell = (JsMenuItemView *)[mcv cellForItemAtIndexPath:nsIndexPath];
			JsMenuItemVm * vm = cell.vm;
			vm.isSelected = NO;
			[cell setupUi];
			//取消选择,需要把maskView也隐藏
		mv_mask.hidden = YES;
		mnsIndexPath_selected = nil;
		}
	}
}

//选中指定序号的item.
- (void)selectItemAtIndex:(int)index {
	NSIndexPath * indexPath = [NSIndexPath indexPathForItem:index inSection:0];
	//代码选择,不需要调用点击事件.
	[self chooseItemAtIndexPath:indexPath isClick:NO];
}

- (NSNumber *)selectedIndex {
	return @(mnsIndexPath_selected.item);
}


#pragma mark 3 InnerFunctin
- (void)moveIndicatorForCell:(UICollectionViewCell *)cell animated:(BOOL)animated {
	CGRect cellFrame = cell.frame;
	CGFloat w = cellFrame.size.width * 0.3;
	CGFloat x = cellFrame.origin.x + (cellFrame.size.width - w)/2;
	CGFloat y = cellFrame.origin.y + cellFrame.size.height * 0.8;
	
	CGFloat h = 1;
	CGRect targetFrame = CGRectMake(x, y, w, h);
	if(animated) {
		[UIView animateWithDuration:0.1 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
			self->mv_indicator.frame = targetFrame;
		} completion:^(BOOL finished) {
		}];
	}
	else {
		self->mv_indicator.frame = targetFrame;
	}
	self->mv_indicator.hidden = NO;
}

#pragma mark 4 Delegate
#pragma mark 4.2 UICollectionView
#pragma mark 4.2.1 UICollectionViewDatasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
	return self->marr.count;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
	JsMenuItemVm * vm = self->marr[indexPath.item];
	if(_delegate && [_delegate respondsToSelector:@selector(jsMenuView:viewForItemAtIndexPath:vm:)]) {
		return [_delegate jsMenuView:self viewForItemAtIndexPath:indexPath vm:vm];
	}
	else {
		JsMenuDefaultItemView * cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellReuseIdentifier forIndexPath:indexPath];
		cell.vm = vm;
		return cell;
	}
}


	//Cell将要显示时的时机,在这里可以设置出厂动画.每个cell只出现一次么?
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
	switch (mgaoMenuViewStyle.inAnimationType) {
		case Prefix(MenuViewInAnimationTypeSpring): {
			cell.transform = CGAffineTransformMakeTranslation(0,300);
			[UIView animateWithDuration:0.8 delay:indexPath.item * 0.02 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveLinear animations:^{
				cell.transform = CGAffineTransformIdentity;
			} completion:^(BOOL finished) {
				
			}];
			break;
		}
		default:{
			break;
		}
	}
	
}


	// 更新对应indexPath的model的状态,然后重新reload.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
	[self chooseItemAtIndexPath:indexPath isClick:YES];

}


#pragma mark 4.2.3 UICollectionViewDelegateFlowLayout
	//返回section和CollectionView容器的边距,top,left,bottom,right;
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
	return mgaoMenuViewStyle.edgeInset;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
	JsMenuItemVm * vm = marr[indexPath.row];
	return vm.currentStyle.cellSize;
}

	//流动方向上cell之间的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
	return mgaoMenuViewStyle.minimumLineSpacing;
}

	//cell之间垂直流动方向上的间距
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
	CGFloat minimumInteritemSpacing = mgaoMenuViewStyle.minimumInteritemSpacing;
	return minimumInteritemSpacing;
}


- (void)reload {
	mb_willReload = YES;
	//reload需要清除上次选择的.
	mnsIndexPath_selected = nil;
		//设置menuView整体样式 menuViewStyle
	if(_delegate && [_delegate respondsToSelector:@selector(jsMenuViewSetStyle:)]){
		mgaoMenuViewStyle = [_delegate jsMenuViewSetStyle:self];
	}
	if(!mgaoMenuViewStyle) {
		mgaoMenuViewStyle = [Prefix(MenuViewStyle) defaultStyle];
	}
	[self setMgaoMenuViewStyle:mgaoMenuViewStyle];
	
	if(_delegate&&[_delegate respondsToSelector:@selector(jsMenuViewSetDatasource:)]) {
		marr = [_delegate jsMenuViewSetDatasource:self];
	}
		//为每个Cell设置样式
	if(marr.count) {
		[marr enumerateObjectsUsingBlock:^(JsMenuItemVm * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
			JsMenuItemStyle * cellStyle = nil;
				//设置cell-unselected样式
			if(_delegate && [_delegate respondsToSelector:@selector(_jsMenuView:setUnselectedStyleForCellAtIndex:)]) {
				cellStyle = [_delegate _jsMenuView:self setUnselectedStyleForCellAtIndex:(int)idx];
			}
			if(cellStyle) {
				obj.unselectedStyle = cellStyle;
			}
			else {
				cellStyle = [JsMenuItemStyle darkModeStyle];
				obj.unselectedStyle = cellStyle;
			}
			
				//设置cell-selected样式
			JsMenuItemStyle * cellStyle_selected = nil;
			if(_delegate && [_delegate respondsToSelector:@selector(_jsMenuView:setSelectedStyleForCellAtIndex:)]) {
				cellStyle_selected = [_delegate _jsMenuView:self setSelectedStyleForCellAtIndex:(int)idx];
			}
			if(cellStyle_selected) {
				obj.selectedStyle = cellStyle_selected;
			}
			else {
					//如果没有设置选中的style,默认和未选中的一样.
				cellStyle_selected = obj.unselectedStyle;
				obj.selectedStyle = cellStyle_selected;
			}
			
				//所有项目都设置为未选择.如果有初始选择的项目,则将该项目赋值为已选择.
			obj.isSelected = NO;
			if(self->mgaoMenuViewStyle.initialSelectedIndex>=0) {
				if(idx == mgaoMenuViewStyle.initialSelectedIndex) {
					mnsIndexPath_selected = [NSIndexPath indexPathForItem:idx inSection:0];
					obj.isSelected = YES;
				}
			}
		}];
	}
	
	
		//处理初始选择的遮罩.
		//这里必须在下一个事件循环中处理,因为reloadData并没有同步调用cellForRow.而是在当前事件循环的后期调用.
		//我们必须等到cellForRow后,布局数据正确后显示遮罩,所以需要放在下一个事件循环.
	dispatch_async(dispatch_get_main_queue(), ^{
		//选择后,立马reload,可能会导致不会刷新,所以放到下一个runloop中.
		[mcv reloadData];
		if(self->mnsIndexPath_selected) {
			[self chooseItemAtIndexPath:mnsIndexPath_selected isClick:NO];
		}
		mb_willReload = NO;
	});
}


/**
 选中指定item,更新UI和相关数据
 @param isClick,是否点击触发
 */
- (void)chooseItemAtIndexPath:(NSIndexPath *)indexPath isClick:(BOOL)isClick {
	
	
		//点击相同的-return;
		//点击相同的是否触发,由用户自己决定,这里都代理出去.
		//	if(mnsIndexPath_selected && indexPath.row == mnsIndexPath_selected.row && indexPath.item == mnsIndexPath_selected.item) {
		//		return;
		//	}
	
		//更新UI
		//更新选中和未选中的样式
	NSMutableArray * marr_reload = [NSMutableArray array];
	if(mnsIndexPath_selected) {
		if(mnsIndexPath_selected.item == indexPath.item && mnsIndexPath_selected.section == indexPath.section) {
				//点击了和上次一样的项目,不用刷新
		}
		else {
			JsMenuItemVm * gaoCvcIlModel_old = marr[mnsIndexPath_selected.item];
			gaoCvcIlModel_old.isSelected = false;
			[marr_reload addObject:mnsIndexPath_selected];
			[marr_reload addObject:indexPath];
		}
	}
	else {
			//第一次选中一个cell
		[marr_reload addObject:indexPath];
	}
	mnsIndexPath_selected = indexPath;
	JsMenuItemVm * gaoCvcIlModel_new = marr[mnsIndexPath_selected.item];
	gaoCvcIlModel_new.isSelected = true;
	if(mb_willReload) {
		
	}
	else {
		//不要reload才执行.
		[UIView performWithoutAnimation:^{
			[mcv reloadItemsAtIndexPaths:marr_reload];
		}];
	}
	//移动浮标 //找到指定IndexPath的cell
	JsMenuItemView * cell = (JsMenuItemView *)[mcv cellForItemAtIndexPath:indexPath];
	if(self->mv_mask.hidden) {
		self->mv_mask.hidden = NO;
		self->mv_mask.frame = cell.frame;
	}
	else {
		[UIView animateWithDuration:0.1 delay:0.1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
			self->mv_mask.frame = cell.frame;
			self->mv_mask.hidden = NO;
		} completion:^(BOOL finished) {
		}];
	}
	if(mv_indicator) {
		if(mv_indicator.hidden) {
			[self moveIndicatorForCell:cell animated:NO];
		}
		else {
				//移动Indicator
			[self moveIndicatorForCell:cell animated:YES];
		}
	}
		//	int i_index_selected = (int)indexPath.row;
		//	mn_selectedIndex = @(i_index_selected);
	mnsIndexPath_selected = indexPath;
	
	
	//点击事件才触发代理,代码选择则不用.
	if(isClick) {
		//事件代理
	if(self.delegate && [self.delegate respondsToSelector:@selector(jsMenuView:clickMenuAtIndex:vm:)]) {
		[self.delegate jsMenuView:self clickMenuAtIndex:(int)indexPath.item vm:marr[indexPath.item]];
	}
	}
}


@end
